package com.netdisk.controller;

import com.netdisk.Domain.StorageBean;
import com.netdisk.Domain.User;
import com.netdisk.component.FileDealCode;
import com.netdisk.dto.file.DownloadFileDTO;
import com.netdisk.dto.file.PreviewDTO;
import com.netdisk.service.HDFSService;
import com.qiwenshare.common.result.RestResult;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@RestController
@RequestMapping("/filetransfer")
public class FileTranserController {
    @Resource
    FileSystem fileSystem;

    @Resource
    HDFSService hdfsService;

    @Resource
    FileDealCode fileDealCode;

    @PostMapping("/uploadfile")
    @ResponseBody
    public RestResult uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        HttpSession session = request.getSession();
        String filePath = session.getAttribute("filePath") + "/" + file.getOriginalFilename();
        Path path = new Path(filePath);
        try {
            // 在HDFS中创建一个新文件
            FSDataOutputStream outputStream = fileSystem.create(path);
            // 将上传的文件内容写入HDFS文件
            outputStream.write(file.getBytes());
            outputStream.close();
            return RestResult.success();
        } catch (IOException e) {
            e.printStackTrace();
            return RestResult.fail().message("上传失败");
        }
    }


    @Operation(summary = "下载文件", tags = {"filetransfer"})
    @RequestMapping(value = "/downloadfile", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<InputStreamResource> downloadFile(HttpServletRequest request, DownloadFileDTO downloadFileDTO) throws IOException {
        HttpSession session = request.getSession();
        String filePath = downloadFileDTO.getUserFileId();
        String oldFilePath = (String) session.getAttribute("filePath");
        String downloadFilePath = null;
        if (filePath.contains(oldFilePath)) {
            downloadFilePath = filePath;
        } else {
            downloadFilePath = oldFilePath + "/" + filePath;
        }
        // 打开文件输入流
        InputStream inputStream = fileSystem.open(new Path(downloadFilePath));
        // 创建响应实体并设置Content-Disposition标头
        HttpHeaders headers = new HttpHeaders();
        if (filePath.contains(oldFilePath)) {
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; " + filePath.substring(filePath.lastIndexOf("/"))); // 设置下载的文件名
        } else {
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; " + filePath); // 设置下载的文件名
        }
        // 返回响应实体
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(new InputStreamResource(inputStream));
    }

    @Operation(summary = "预览文件", description = "用于文件预览", tags = {"filetransfer"})
    @GetMapping("/preview")
    public ResponseEntity preview(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, PreviewDTO previewDTO) throws IOException {
        HttpSession session = httpServletRequest.getSession();
        String extendName = previewDTO.getExtendName();
        User user = (User) session.getAttribute("user");
        String hdfsPath = "/" + user.getTelephone() + previewDTO.getFilePath();
        Path imagePath = new Path(hdfsPath);

        if (fileSystem.exists(imagePath)) {
            // 打开文件流并读取图片内容
            try (FSDataInputStream inputStream = fileSystem.open(imagePath)) {
                // 读取图片内容到字节数组
                byte[] imageData = new byte[inputStream.available()];
                inputStream.readFully(imageData);
                // 将Base64编码的图片内容解码为字节数组
                byte[] data = Base64.getEncoder().encode(imageData);
                // 设置HTTP响应头，指定响应内容为图片类型
                HttpHeaders headers = new HttpHeaders();
                // 适应您的文件类型
                headers.setContentType(MediaType.parseMediaType(FileDealCode.getContentType("." + extendName)));
                // 创建包含图片内容的响应实体
                return new ResponseEntity<>(imageData, headers, HttpStatus.OK);
            }
        } else {
            System.out.println("文件不存在！");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @GetMapping("/getstorage")
    public RestResult getStorage(HttpServletRequest httpServletRequest) throws IOException {
        StorageBean storage = new StorageBean();
        HttpSession session = httpServletRequest.getSession();
        User user = (User)session.getAttribute("user");
        storage.setStorageSize(hdfsService.getSize("/" + user.getTelephone()));
        return RestResult.success().data(storage);
    }
}
